home *** CD-ROM | disk | FTP | other *** search
/ The 640 MEG Shareware Studio 2 / The 640 Meg Shareware Studio CD-ROM Volume II (Data Express)(1993).ISO / pascal / tpb4_src.zip / DIRS.PAS < prev    next >
Pascal/Delphi Source File  |  1988-09-13  |  13KB  |  444 lines

  1. { TPBoard 4.2 Copyright (c) 1987,88 by Jon Schneider & Rick Petersen  
  2.   Portions Copyright (c) 1986,87 by Steve Fox and Les Archambault  
  3.   
  4.   Last modified  ::  3-24-88 8:46 pm 
  5. }
  6.  
  7. {$R-}                             {Range checking off}
  8. {$B-}                             {Boolean complete evaluation off}
  9. {$S-}                             {Stack checking off}
  10. {$I+}                             {I/O checking on}
  11. {$N-}                             {No numeric coprocessor}
  12.  
  13. Unit Dirs;
  14.  
  15. Interface
  16.  
  17. Uses
  18.   TPCrt, Dos, Globals, Core1,
  19.   Core2, Extract;
  20.   
  21.   
  22. function compress_fn(name : DosFileName) : DosFileName;
  23.  
  24. function correct_fn(Str : DosFileName) : DosFileName;
  25.  
  26. procedure ReadDir(var entries     : Word;
  27.                   var space_used  : LongInt;
  28.                   var first       : FilePtr);
  29.                   
  30. procedure LibReadDir(var entries     : Word;
  31.                      var space_used  : LongInt;
  32.                      var first       : FilePtr);
  33.                      
  34. procedure ArcReadDir(var entries     : Word;
  35.                      var space_used  : LongInt;
  36.                      var first       : FilePtr);
  37.                      
  38. function Expand_Filename(tfname : DosFileName) : DosFileName;
  39.  
  40. function Equal_names(test, target : DosFileName) : Boolean;
  41.  
  42.  
  43.   {==========================================================================}
  44.   
  45.   
  46. Implementation
  47.  
  48.  
  49.   procedure InsertFile(fname           : name_array;
  50.                        index           : Word;
  51.                        size            : LongInt;
  52.                        attrib          : Byte;
  53.                        var entries     : Word;
  54.                        var total       : LongInt;
  55.                        var first       : FilePtr);
  56.     { Insert a new file name into an alphabetic list }
  57.     
  58.   var
  59.     space           : LongInt;
  60.     F,                            { File name entry being created }
  61.     This, last      : FilePtr;    { Followers for insertion }
  62.     fn              : DosFileName;
  63.     
  64.   begin
  65.     fn := '           ';          { Initialize string }
  66.     Move(fname, fn[1], 11);       { Move name into place }
  67.     Insert('.', fn, 9);
  68.     last := nil;
  69.     This := first;
  70.     while (This <> nil) and (This^.fname < fn) do
  71.       begin
  72.         last := This;
  73.         This := This^.next
  74.       end;
  75.     space := size shr 3;
  76.     if (size mod 8) <> 0 then
  77.       Inc(space);
  78.     if This^.fname <> fn then
  79.       begin
  80.         Inc(entries);
  81.         total := total+space;
  82.         New(F);
  83.         F^.fname := fn;
  84.         F^.index := index;
  85.         F^.fsize := size;
  86.         F^.attrib := attrib;
  87.         F^.next := This;
  88.         if last = nil then
  89.           first := F
  90.         else
  91.           last^.next := F
  92.       end
  93.     else if (This^.fname = fn) and (This^.fsize < size) then
  94.       begin
  95.         total := total+space;
  96.         space := This^.fsize shr 3;
  97.         if (This^.fsize mod 8) <> 0 then
  98.           Inc(space);
  99.         total := total-space;
  100.         This^.fsize := size
  101.       end
  102.   end;
  103.   
  104.   
  105.   function compress_fn(name : DosFileName) : DosFileName;
  106.     { Strip hi bits and remove all blanks from file name }
  107.     
  108.   var
  109.     i               : Integer;
  110.     
  111.   begin
  112.     for i := 1 to Length(name) do
  113.       name[i] := Chr($7F and Ord(name[i]));
  114.     i := Pos(' ', name);
  115.     while i > 0 do
  116.       begin
  117.         Delete(name, i, 1);
  118.         i := Pos(' ', name)
  119.       end;
  120.     compress_fn := name
  121.   end;
  122.   
  123.   
  124.   
  125.   function correct_fn(Str : DosFileName) : DosFileName;
  126.     { Correct possible errors in file name }
  127.     
  128.   var
  129.     i, J            : Integer;
  130.     
  131.   begin
  132.     i := 1;                       { Remove blanks and invalid characters }
  133.     while i <= Length(Str) do
  134.       if Str[i] in [' ', '*', ',', ':', ';', '=', '?', '+', '[', ']', '/'] then
  135.         Delete(Str, i, 1)
  136.       else
  137.         Inc(i);
  138.     while (Str <> '') and (Str[1] = '.') do { Remove leading '.' }
  139.       Delete(Str, 1, 1);
  140.     i := Pos('.', Str);           { Remove redundant '.' }
  141.     J := 1;
  142.     while J <= Length(Str) do
  143.       if (Str[J] = '.') and (J > i) then
  144.         Delete(Str, J, 1)
  145.       else
  146.         Inc(J);
  147.     i := Pos('.', Str);
  148.     if i = 0                      { Ensure name has '.' }
  149.     then
  150.       begin
  151.         Str := Copy(Str, 1, 8);   { Ensure file name <= 8 characters }
  152.         if Length(Str) > 0 then
  153.           Str := Str+'.'
  154.       end
  155.     else
  156.       Str := Copy(Str, 1, min(8, Pred(i)))+'.'+Copy(Str, Succ(i), min(3, Length(Str)-i));
  157.     correct_fn := Str
  158.   end;
  159.   
  160.   
  161.   
  162.   procedure ReadDir(var entries     : Word;
  163.                     var space_used  : LongInt;
  164.                     var first       : FilePtr);
  165.     { Create an alphabetized list of files in the current file area }
  166.     
  167.   var
  168.     This            : FilePtr;
  169.     file_name       : name_array;
  170.     mask            : StrPr;
  171.     FileSize        : LongInt;
  172.     DirInfo         : SearchRec;
  173.     Attribute       : Word;
  174.     
  175.     
  176.     procedure fillrec;
  177.     
  178.     var
  179.       i, x            : Integer;
  180.       work            : string[12];
  181.       
  182.     begin
  183.       work := DirInfo.name;
  184.       FillChar(file_name, 11, ' ');
  185.       x := 1;
  186.       i := 1;
  187.       while (work[i] <> Chr(0)) and (i <= Length(work)) do
  188.         begin
  189.           if work[i] = '.' then
  190.             begin
  191.               x := 9;
  192.               Inc(i);
  193.             end
  194.           else
  195.             begin
  196.               file_name[x] := Ord(work[i]);
  197.               Inc(x);
  198.               Inc(i);
  199.             end;
  200.         end;
  201.       with DirInfo do
  202.         begin
  203.           FileSize := size div 128;
  204.           if Chr(file_name[1]) <> ' ' then
  205.             InsertFile(file_name, 0, FileSize, attr, entries, space_used, first);
  206.         end;
  207.     end;
  208.     
  209.   begin                           {ReadDir}
  210.     new_dir := True;
  211.     space_used := 0;
  212.     while first <> nil do         { Clean out any old directory list }
  213.       begin
  214.         This := first;
  215.         first := first^.next;     { Go to next on chain }
  216.         Dispose(This)             { Reclaim space }
  217.       end;
  218.     DirEntries := 0;
  219.     mask := '????????.???'+Chr(0);
  220.     if ((user_rec.access >= 250) and (mode <> sysop_mode)) or ((not remote_copy)
  221.       and (mode <> sysop_mode)) then
  222.       Attribute := 39
  223.     else
  224.       Attribute := 33;
  225.     SetSect(SetName);
  226.     FindFirst(mask, Attribute, DirInfo);
  227.     if DosError = 0 then
  228.       begin
  229.         fillrec;                  {enter data into linked list}
  230.         repeat
  231.           FindNext(DirInfo);
  232.           if DosError = 0 then fillrec;
  233.         until DosError <> 0;
  234.       end;
  235.     free_space := diskfree(0) div 1024; {current directory}
  236.     SetSect(HomName)
  237.   end;
  238.   
  239.   
  240.   
  241.   procedure LibReadDir(var entries     : Word;
  242.                        var space_used  : LongInt;
  243.                        var first       : FilePtr);
  244.     { Read library directory }
  245.     
  246.   var
  247.     i, off, result  : Integer;
  248.     This            : FilePtr;
  249.     LibBlock        : array[0..3] of EntryBlock;
  250.     
  251.   begin
  252.     SetSect(SetName);
  253.     Assign(libr_file, LibReq);
  254.     {$I-}
  255.     Reset(libr_file, 1) {$I+} ;
  256.     if (IoResult = 0) and (FileSize(libr_file) > 0) then
  257.       begin
  258.         while first <> nil do     { Clean out any old directory list }
  259.           begin
  260.             This := first;
  261.             first := first^.next; { Go to next on chain }
  262.             Dispose(This)         { Reclaim space }
  263.           end;
  264.         {$I-}
  265.         BlockRead(libr_file, LibBlock, 128, result) {$I+} ;
  266.         in_library := (IoResult = 0);
  267.         i := 1;
  268.         while in_library and (i < 11) do
  269.           if LibBlock[0].fname[i] = $20 then
  270.             Inc(i)
  271.           else
  272.             in_library := False;
  273.         in_library := in_library and (LibBlock[0].status = 0);
  274.         if in_library then
  275.           begin
  276.             new_dir := True;
  277.             space_used := 0;
  278.             LibEntries := 0;
  279.             for i := 1 to Pred(LibBlock[0].fsize shl 2) do
  280.               begin
  281.                 off := i mod 4;
  282.                 if off = 0 then
  283.                   BlockRead(libr_file, LibBlock, 128, result);
  284.                 with LibBlock[off] do
  285.                   if status < $FE then
  286.                     InsertFile(fname, index, fsize, 0, entries, space_used, first)
  287.               end
  288.           end
  289.       end
  290.     else
  291.       begin
  292.         WriteLn(com, 'Error opening Lbr File ', LibReq, '.');
  293.         new_dir := False;
  294.       end;
  295.     {$I-}
  296.     Close(libr_file) {$I+} ;
  297.     SetSect(HomName)
  298.   end;
  299.   
  300.   
  301.   
  302.   procedure ArcReadDir(var entries     : Word;
  303.                        var space_used  : LongInt;
  304.                        var first       : FilePtr);
  305.                        
  306.   var
  307.     i, x, size      : Integer;
  308.     extname         : name_array;
  309.     This            : FilePtr;
  310.     OK              : Boolean;
  311.     
  312.   begin                           {ArcReadDir}
  313.     SetSect(SetName);
  314.     Assign(arc_file, ArcReq);
  315.     {$I-}
  316.     Reset(arc_file, 1) {$I+} ;
  317.     if (IoResult = 0) and (FileSize(arc_file) > 0) then
  318.       begin
  319.         while first <> nil do     { Clean out any old directory list }
  320.           begin
  321.             This := first;
  322.             first := first^.next; { Go to next on chain }
  323.             Dispose(This)         { Reclaim space }
  324.           end;
  325.         new_dir := True;
  326.         OK := True;
  327.         ArcSpace := 0;
  328.         ArcEntries := 0;
  329.         while (Read_Arc_Hdr) and OK do
  330.           begin
  331.             in_arc := True;
  332.             FillChar(extname, 11, ' ');
  333.             i := 1;
  334.             x := 1;
  335.             while ((Hdr.name[i-1] <> #0) and (i < 14) and (x < 12)) do
  336.               begin
  337.                 if Hdr.name[i-1] = '.' then
  338.                   x := 9
  339.                 else
  340.                   begin
  341.                     extname[x] := Ord(Upcase(Hdr.name[i-1]));
  342.                     Inc(x);
  343.                   end;
  344.                 Inc(i);
  345.               end;
  346.             if Hdr.size < 128 then
  347.               size := 1
  348.             else if Hdr.size > 4194176 then { maximum file size }
  349.               OK := False
  350.             else
  351.               size := Hdr.size div 128;
  352.             if OK then
  353.               begin
  354.                 InsertFile(extname, 0, size, 0, entries, space_used, first);
  355.                 {$I-}
  356.                 Seek(arc_file, (FilePos(arc_file)+Hdr.size)) {$I+} ;
  357.                 OK := (IoResult = 0);
  358.               end;
  359.           end;                    {reading arc file header}
  360.         if (not OK) then
  361.           WriteLn(com, 'Warning! Error reading Arc file ', ArcReq, '.');
  362.       end
  363.     else
  364.       begin
  365.         WriteLn(com, 'Error opening Arc File ', ArcReq, '.');
  366.         new_dir := False;
  367.       end;
  368.     {$I-}
  369.     Close(arc_file) {$I+} ;
  370.     SetSect(HomName);
  371.   end;                            {ArcReadDir}
  372.   
  373.   
  374.   function Expand_Filename(tfname : DosFileName) : DosFileName;
  375.     { Expands filename to 12 characters and expands wildcards}
  376.     
  377.   var
  378.     work_name       : DosFileName;
  379.     n, x, K         : Integer;
  380.     
  381.   begin
  382.     work_name := '            ';
  383.     work_name[9] := '.';
  384.     x := 1;
  385.     K := 1;
  386.     while (x <= Length(tfname)) and (K < 13) do
  387.       begin
  388.         if tfname[x] = '.' then
  389.           begin
  390.             K := 10;
  391.             Inc(x);
  392.           end;
  393.         if tfname[x] = '*' then
  394.           begin
  395.             if K < 9 then
  396.               begin
  397.                 for n := K to 8 do
  398.                   work_name[n] := '?';
  399.                 K := 10;
  400.               end
  401.             else
  402.               begin
  403.                 if K > 9 then
  404.                   for n := K to 12 do
  405.                     work_name[n] := '?';
  406.                 K := 13;
  407.               end;
  408.           end
  409.         else
  410.           work_name[K] := tfname[x];
  411.         Inc(x);
  412.         Inc(K);
  413.       end;
  414.     Expand_Filename := work_name;
  415.   end;
  416.   
  417.   
  418.   
  419.   function Equal_names(test, target : DosFileName) : Boolean;
  420. { tests equality of two filenames including wildcards expanded
  421.   with the Expand_filename function}
  422.   
  423.   var
  424.     x               : Integer;
  425.     match           : Boolean;
  426.     
  427.   begin
  428.     match := True;
  429.     for x := 1 to Length(test) do
  430.       test[x] := Chr($7F and Ord(test[x])); {strip hi bit}
  431.     for x := 1 to Length(target) do
  432.       target[x] := Chr($7F and Ord(target[x])); {strip hi bit}
  433.     x := 1;
  434.     repeat
  435.       if (test[x] <> '?') and (test[x] <> target[x]) then
  436.         match := False;
  437.       Inc(x);
  438.     until (match = False) or (x > Length(test));
  439.     Equal_names := match;
  440.   end;
  441.   
  442. end.                              { of DIRS.PAS}
  443. 
  444.